跳到主要内容

二维矩阵(Mat2D)

表示一个二维变换矩阵,包含缩放、 旋转、错切和平移分量。

-- 手动构建矩阵
local m = Mat2D.identity()

m.xx = 2 -- 缩放 x
m.yy = 3 -- 缩放 y
m.tx = 50 -- 平移 x
m.ty = 100 -- 平移 y

local r = m * Vector.xy(10, 20)

-- (10,20) → (20,60) → (70,160)
print(r.x, r.y) -- 70, 160

字段(Fields)

xx

矩阵的 xx 分量。

local m = Mat2D.identity()

-- 水平缩放加倍
m.xx = 2

local r = m * Vector.xy(10, 5)
print(r.x, r.y) -- 20, 5

xy

矩阵的 xy 分量。

local m = Mat2D.identity()

-- 添加水平错切
m.xy = 1

local r = m * Vector.xy(10, 5)
-- x = 10 + (1 * 5)
print(r.x, r.y) -- 15, 5

yx

矩阵的 yx 分量。

local m = Mat2D.identity()

-- 添加垂直错切
m.yx = 1

local r = m * Vector.xy(10, 5)
-- y = 5 + (1 * 10)
print(r.x, r.y) -- 10, 15

yy

矩阵的 yy 分量。

local m = Mat2D.identity()

-- 垂直缩放三倍
m.yy = 3

local r = m * Vector.xy(4, 5)
print(r.x, r.y) -- 4, 15

tx

沿 x 轴的平移量。

local m = Mat2D.identity()

m.tx = 50

local r = m * Vector.xy(10, 20)
print(r.x, r.y) -- 60, 20

ty

沿 y 轴的平移量。

local m = Mat2D.identity()

m.ty = 100

local r = m * Vector.xy(10, 20)
print(r.x, r.y) -- 10, 120

withTranslation

根据给定的 x 和 y 值或 Vector 位置创建平移矩阵。

-- 从数值创建
local t1 = Mat2D.withTranslation(50, 100)

-- 从 Vector 创建
local pos = Vector.xy(50, 100)
local t2 = Mat2D.withTranslation(pos)

withScale

根据给定的 x 和 y 值或 Vector 创建缩放矩阵。

-- 均匀缩放(如果省略 y,则默认与 x 相同)
local s1 = Mat2D.withScale(2)

-- 非均匀缩放
local s2 = Mat2D.withScale(2, 3)

-- 从 Vector 创建
local scale = Vector.xy(2, 3)
local s3 = Mat2D.withScale(scale)

withScaleAndTranslation

根据数值或向量创建缩放并平移矩阵。

-- 数值重载

-- 先缩放 (2, 3),再平移 (50, 100)
local st = Mat2D.withScaleAndTranslation(2, 3, 50, 100)

local p = Vector.xy(10, 20)
local r = st * p

-- (10,20) -> 缩放后 (20,60) -> 平移后 (70,160)
print(r.x, r.y) -- 70, 160

-- 向量重载

local st = Mat2D.withScaleAndTranslation(
Vector.xy(2, 3), -- 缩放
Vector.xy(50, 100) -- 位置 / 平移
)

local r = st * Vector.xy(10, 20)
print(r.x, r.y) -- 70, 160

构造器(Constructors)

values

values(xx: number, xy: number, yx: number, yy: number, tx: number, ty: number) -> Mat2D

使用指定的各分量创建矩阵。

-- xx=1, xy=skewX(水平错切), yx=skewY(垂直错切), yy=1, tx=0, ty=0
local newMat = Mat2D.values(1, self.skewY, self.skewX, 1, 0, 0)

identity

identity() -> Mat2D

返回单位矩阵。

-- xx = 1, xy = 0, yx = 0, yy = 1, tx = 0, ty = 0
local newMat = Mat2D.identity()

withRotation

withRotation(radians: number) -> Mat2D

根据给定的弧度角创建旋转矩阵。

local rot = Mat2D.withRotation(math.rad(90))
local r = rot * Vector.xy(1, 0)

print(math.floor(r.x + 0.5), math.floor(r.y + 0.5)) -- 0, 1

静态函数(Static Functions)

invert

invert(output: Mat2D, input: Mat2D) -> boolean

将 'input' 的逆矩阵写入 'output'。如果输入矩阵可逆则返回 true。

local m = Mat2D.withTranslation(50, 100)

local inv = Mat2D.identity()
local ok = Mat2D.invert(inv, m)
print(ok) -- true

local p = Vector.xy(10, 20)
local r = inv * (m * p)

-- 先应用 m 再应用 inv 会返回原始点
print(r.x, r.y) -- 10, 20

方法(Methods)

invert

invert() -> Mat2D?

提供对矩阵分量的索引访问。

local m = Mat2D.identity()

-- 索引映射:xx, xy, yx, yy, tx, ty
m[1] = 2 -- xx
m[5] = 50 -- tx

print(m[1], m.xx) -- 2, 2
print(m[5], m.tx) -- 50, 50

返回矩阵的逆矩阵,如果矩阵不可逆则返回 nil。

local m = Mat2D.withTranslation(50, 100)
local inv = m:invert()

if inv then
local p = Vector.xy(10, 20)
local result = inv * (m * p)
print(result.x, result.y) -- 10, 20
end

isIdentity

isIdentity() -> boolean

如果矩阵为单位变换则返回 true。

local newMat = Mat2D.identity()
print(newMat:isIdentity())

__eq

__eq(rhs: Mat2D) -> boolean

如果两个矩阵的所有分量都相等则返回 true。

local a = Mat2D.values(1, 0, 0, 1, 0, 0)
local b = Mat2D.identity()

print(a == b) -- true

__mul

__mul(rhs: Vector) -> Vector

用矩阵变换给定的 Vector 并返回结果。

local translation = Mat2D.values(1, 0, 0, 1, 50, 100)
local point = Vector.xy(10, 20)

-- 矩阵乘以向量
local result = translation * point

print(result.x, result.y) -- 60, 120

__mul

__mul(rhs: Mat2D) -> Mat2D

返回此矩阵与给定矩阵的矩阵乘积。

local translation = Mat2D.values(1, 0, 0, 1, 50, 100)
local scale = Mat2D.values(2, 0, 0, 2, 0, 0)

-- 组合变换
local combined = translation * scale

local point = Vector.xy(10, 20)
local result = combined * point

print(result.x, result.y) -- 70, 140